<!-- subpkg_consult/room/index.vue -->
<script lang="ts" setup>
import { useUserStore } from '@/stores/user';
import { io, type Socket} from 'socket.io-client'
import RoomStatus from './components/room-status.vue'
import { ref } from 'vue';
import type { OrderDetail } from '@/types/consult';
import { orderDetailApi, uploadImageApi } from '@/apis/consult';
import type { MsgData, MsgItem } from '@/types/room';
import PatientInfo from './components/patient-info.vue'
import NotifyInfo from './components/notify-info.vue';
import MessageInfo from './components/message-info.vue'
import PrescriptionInfo from './components/prescription-info.vue';
import { OrderType } from '@/enums/index'
import { nextTick } from 'vue';

const store = useUserStore()

// 1. 获取地址栏参数
const props = defineProps<{
  orderId: string
  payResult: string
}>()

if(props.payResult === 'false'){
  uni.reLaunch({
    url:'/pages/my/index',
  })
}

// 2. 建立socket连接
const socket: Socket = io('https://consult-api.itheima.net', {
  auth: { token: 'Bearer ' + store.token},
  query: {orderId: props.orderId},
  transports: ['websocket', 'polling'],
  timeout: 5000
})

socket.on('connect', () => {
  // 建立连接成功
  console.log('连接建立成功')
})

socket.on('error', (event) => {
  // 错误异常消息
  console.log('出现错误')
})

socket.on('disconnect', () => {
  // 已经断开连接
  console.log('断开连接')
})

// 3. 获取订单详情
const orderDetail = ref<OrderDetail>()
const getOrderDetail = async ()=>{
  if(!props.orderId) return uni.showToast({title: '没有订单, 请重新生成', mask: false})
  const res = await orderDetailApi(props.orderId)
  console.log(res);
  orderDetail.value = res
}
getOrderDetail()

// 4. 接收订单状态变化
socket.on('statusChange', (data)=>{
  // console.log(data);
  // 重新获取订单详情
  getOrderDetail()
})

// 5. 接收历史消息
const messageList = ref<MsgItem[]>([])
socket.on('chatMsgList', (res: MsgData)=>{
  // console.log(res);
  if(res.code !== 10000) return uni.showToast({title: '获取历史消息失败', icon: 'none'})

  res.data?.forEach(item => {
    messageList.value.push({
      id: item.createTime,
      msgType: 31,
      msg: {
        content: item.createTime
      }
    },...item.items!)
  })  
})

// 6. 接收消息
socket.on('receiveChatMsg', (res: MsgItem)=>{
  // 6.1 标明消息已读
  socket.emit('updateMsgStatus', res.id)

  // 6.2 把消息加入消息数组
  messageList.value.push(res)

  // 6.3 让scroll-view滚动到最底部
  // vue中数据是同步更新, 视图是异步更新
  // 为了保证渲染的高效性, 会把一个宏任务期间的所有改变收集到一起, 一次性更新视图
  nextTick(()=>{
    sp.value = `item${messageList.value.length - 1}`
  })
})

// 7. 咨询其它医生
const goToHome = ()=>{
  uni.switchTab({
    url:'/pages/index/index',
  })
}

// 8. 发送文字
const words = ref('')
const sendText = (e: any)=>{
  // 8.1 判断
  if(words.value.trim() === '') return uni.showToast({title: '输入内容不能为空', icon: 'none'})
  if (!store.userId) return uni.showToast({ title: '请重新登录', icon: 'none' })
  if (!orderDetail.value?.docInfo) return uni.showToast({ title: '当前问诊出现数据问题', icon: 'none' })

  // 8.2 包装一个文字消息对象发给服务器
  socket.emit('sendChatMsg', {
    from: store.userId,
    to: orderDetail.value?.docInfo?.id,
    msgType: 1,
    msg: {
      content: words.value.trim()
    }
  })

  // 8.3 清空输入框
  words.value = ''
  
}


// 9. 发送图片
const sendImage = async ()=>{
  // 9.1 判断当前是否是咨询中
  if(orderDetail.value?.status !== 3){
    return uni.showToast({title: '医生当前不在线~', icon: 'none'})
  }

  // 9.2 从本地获取图片
  const imgFile = await uni.chooseImage({
    count: 1,
  })
  // console.log(imgFile.tempFilePaths[0]);

  // 9.3 上传图片
  const res = await uploadImageApi(imgFile.tempFilePaths[0])
  // console.log(res);

  // 9.4 发送图片消息
  socket.emit('sendChatMsg', {
    from: store.userId,
    to: orderDetail.value?.docInfo?.id,
    msgType: 4,
    msg: {
      picture: res
    }
  })
}

// 10. 消息滚动
const sp = ref('')

</script>

<template>
  <view class="room-page">
    <!-- 问诊室的状态 -->
    <room-status v-if="orderDetail" :status="orderDetail.status" :status-value="orderDetail.statusValue"
      :countdown="orderDetail.countdown" />

    <scroll-view refresher-enabled refresher-background="#f2f2f2" scroll-y style="flex: 1; overflow: hidden"
      :scroll-into-view="sp">
      <!-- <view class="message-container"></view> -->
      <view v-for="(item, i) in messageList" :key="item.id" :id="`item${i}`">
        <!-- 患者信息卡片 -->
        <PatientInfo v-if="item.msgType === 21" :info="item.msg?.consultRecord!" />
        <!-- 消息通知卡片 -->
        <NotifyInfo v-if="item.msgType! >= 31" :type="item.msgType">
          {{ item.msg?.content }}
        </NotifyInfo>
        <!-- 文字和图片消息卡片 -->
        <MessageInfo v-if="item.msgType! <= 4" :type="item.msgType!" :info="item" />
        <PrescriptionInfo v-if="item.msgType === 22" :info="item.msg?.prescription!" />
      </view>
    </scroll-view>

    <!-- 发送消息 -->
    <view class="message-bar">
      <template v-if="orderDetail?.status === OrderType.ConsultWait || orderDetail?.status === OrderType.ConsultChat ">
        <uni-easyinput v-model="words" :disabled="orderDetail?.status === OrderType.ConsultWait" :clearable="false"
          :input-border="false" placeholder-style="font-size: 32rpx; color: #c3c3c5;" placeholder="问医生"
          @change="sendText" />
        <view class="image-button">
          <uni-icons size="40" color="#979797" type="image" @click="sendImage"></uni-icons>
        </view>
      </template>
      <button v-else class="uni-button" @click="goToHome">咨询其它医生</button>
    </view>
  </view>
</template>

<style lang="scss">
@import './index.scss';
</style>